package plp.expressions2.memory;

import java.util.HashMap;
import java.util.Stack;

import plp.expressions2.expression.Id;
import plp.expressions2.expression.Valor;
import plp.expressions2.memory.ListaValor;

public class ContextoExecucao extends Contexto<Valor> implements AmbienteExecucao {

	private static ListaValor saida = new ListaValor();


	@Override
	public ContextoExecucao clone() throws CloneNotSupportedException {
		ContextoExecucao c = new ContextoExecucao();
		c.setPilha((Stack<HashMap<Id, Valor>>) super.getPilha().clone());
		return c;
	}

	public Stack<HashMap<Id, Valor>> getPilha(){
		return super.getPilha();
	}
	
	public ListaValor getSaida() {
		return saida;    
	}

	public void write(Valor v){
		saida.write(v);
	}
	
	public static void clearListaValor(){
		saida = new ListaValor();
	}

	// só funciona se tiver na pilha do processo
	public void changeValor(Id idArg, Valor valorId) throws VariavelNaoDeclaradaException {		
		Object result = null;
		Stack<HashMap<Id,Valor>> auxStack = new Stack<HashMap<Id,Valor>>();
		Stack<HashMap<Id,Valor>> stack = this.getPilha();

		while (result == null && !stack.empty()) {
			HashMap<Id,Valor> aux = stack.pop();
			auxStack.push(aux);
			result = aux.get(idArg);
			if (result != null) {
				aux.put(idArg, valorId);
			}
		}
		
		while (!auxStack.empty()) {
			stack.push(auxStack.pop());
		}
		
		if (result == null) {
			throw new VariavelNaoDeclaradaException(idArg);
		}
	}

}